module mpc(instr,out);
input[17:0] instr;//instr 为输入的指令
output[8:0] out;//输出结果
reg [8:0] out;
reg func;
reg [7:0] op1, op2;     //从指令中提取的两个操作数

function [16:0] code_add;//函数的定义
    input[17:0] instr;
    reg add_func;
    reg[7:0] code,opr1,opr2;

    begin
        code = instr[17:16];//输入指令 inst 的高 2 位是操作码
        opr1 = instr[7:0];  //输入指令 instr 的低 8 位是操作数 opr1
        case(code)
        2'b00: begin
            add_func=1;
            opr2=instr[15:8];//从 instr 中取第二个操作数
        end
        2'b01: begin
            add_func=0;
            opr2=instr[15:8];//从 instr 中取第二个操作数
        end
        2'b10: begin
            add_func=1;
            opr2=8'd1;//第二个操作数取为 1，实现+1 操作
        end
        default: begin
            add_func=0;
            opr2=8'd1;//实现-1 操作
        end
        endcase
        code_add={add_func, opr2, opr1};
    end
endfunction

always @(instr) begin
    {func,op2,op1}=code_add(instr);//调用函数
    if(func==1)
        out=op1+op2;//实现两数相加操作数 1 加 1 作
    else begin 
        out=op1 - op2;//实现两数相减、操作数 1 减 1 操作
    end
end

endmodule



`timescale 10ns/1ns
module mpc_tp;
reg[17:0] instr;
wire[8:0] out;
parameter DELY=10;

mpc m1(instr, out);//例化待测试模块

initial begin
    instr=18'd0;
    #DELY instr=18'b00_01001101_00101111;
    #DELY instr=18'b00_11001101_11101111;
    #DELY instr=18'b01_01001101_11101111;
    #DELY instr=18'b01_01001101_00101111;
    #DELY instr=18'b10_01001101_00101111;
    #DELY instr=18'b11_01001101_00101111;
    #DELY instr=18'b00_01001101_00101111;
    #DELY $finish;
end

initial $monitor($time,,,"instr=%b out=%b",instr,out);

wire [1:0] opcode = instr[17:16];
wire [7:0] op2    = instr[15:8];
wire [7:0] op1    = instr[7:0];
wire       cout   = out[8];
wire [7:0] res    = out[7:0];


initial begin
    $dumpfile("dump.vcd");   //生成的 vcd 文件名称
    $dumpvars(0, mpc_tp);    //dump 所需变量
    #1000 $finish;
end

endmodule